Colors {
    Colors.black = rgba(0.0, 0.0, 0.0, 1.0)
    Colors.gray = rgba(0.8, 0.8, 0.8, 1.0)
    Colors.darkgray = rgba(0.6, 0.6, 0.6, 1.0)
    Colors.red = rgba(1.0, 0.0, 0.0, 1.0)
    -- Colors.pink = rgba(1.0, 0.4, 0.7, 1.0)
    Colors.yellow = rgba(1.0, 1.0, 0.0, 1.0)
    Colors.orange = rgba(1.0, 0.6, 0.0, 1.0)
    Colors.lightorange = rgba(1.0, 0.6, 0.0, 0.25)
    Colors.green = rgba(0.0, 1.0, 0.0, 1.0)
    Colors.blue = rgba(0.0, 0.0, 1.0, 1.0)
    Colors.lightblue = rgba(0.0, 0.0, 1.0, 0.25)
    Colors.cyan = rgba(0.0, 1.0, 1.0, 1.0)
    Colors.purple = rgba(0.5, 0.0, 0.5, 1.0)
    Colors.white = rgba(1.0, 1.0, 1.0, 1.0)
    Colors.none = rgba(0.0, 0.0, 0.0, 0.0)
    Colors.lightblue2 = rgba(0.82, 0.88, 0.94, 1.0)

    Colors.sky = rgba(0.42, 0.65, 0.77, 1.0)
    Colors.lightsky = rgba(0.252, 0.65, 0.77, 0.25)
    Colors.pink = rgba(0.78, 0.256, 0.53, 1.0)
    Colors.lightpink = rgba(0.78, 0.256, 0.53, 0.25)
    Colors.bluegreen = rgba(0.44, 0.68, 0.60, 1.0)
}

global {
       global.pi_over_four = 0.78
       global.half_pi = 1.57
       global.pi = 3.14
       global.two_pi = 6.28
}

Set x {
    x.shape = RectangleTransform {
        strokeWidth = 0
	-- sizeX = 400.0
	-- sizeY = OPTIMIZED
	-- rotation = OPTIMIZED
    }
    -- TODO: make sure this starts in the origin of screen space?
    -- Note: rotations are only applied in frontend, so we don't optimize WRT them yet.

    x.text = Text {
      string = x.label
      x = x.shape.x -- TODO: need to apply the transform, otherwise x and y are still 0
      y = x.shape.y
    }

    -- x.labelFn = ensure contains(x.shape, x.text)
    -- x.minSizeFn = ensure minSize(x.shape)
    -- x.maxSizeFn = ensure maxSize(x.shape)
    -- x.labelPosFn = encourage sameCenter(x.text, x.shape)
    LOCAL.layering  = x.shape below x.text
}

Set `A` {
    `A`.shape.color = Colors.red
    `A`.y = OPTIMIZED -- Note: transform needs to include DOF explicitly. Is that ok?

    -- So all the DOF in an HMatrix should start as DOF
    -- They could be set by some computation--in which case they are no longer DOF
    -- Just like how "x" was a DOF unless set by a computation
    -- Some transform could introduce additional DOF (which need to be named)
    -- Transforms could be combined in the final matrix
    -- Set the default hmatrix and have its DOF
    -- Then varyingPaths needs to access inside of an hmatrix

    `A`.shape.transform = translate(0.0, `A`.y)
    `A`.transformFn = encourage nearT(`A`.shape, 0.0, 0.0)
}

Set `B` {
    `B`.shape.color = Colors.green
    `B`.shape.transform = andThen(translate(100.0, 0.0), rotate(global.pi_over_four))
    -- TODO: test/debug rotateAbout
    -- `B`.shape.transform = rotateAbout(global.half_pi, 100.0, 100.0)
}

Set `C` {
    `C`.shape.color = Colors.blue
    `C`.shape.transform = andThen(rotate(global.half_pi), translate(100.0, 0.0))
}

Set x; Set y
where IsSubset(x, y) {
    -- LOCAL.containFn = ensure contains(y.shape, x.shape)
    -- LOCAL.sizeFn    = ensure smallerThan(x.shape, y.shape)
    -- LOCAL.outsideFn = ensure outsideOf(y.text, x.shape)
    LOCAL.layering  = x.shape above y.shape
    LOCAL.layering1  = y.text below x.shape
}

Set x; Set y
where NotIntersecting(x, y) {
    LOCAL.notIntersectFn = ensure disjoint(x.shape, y.shape)
}

Set x; Set y
where Intersect(x, y) {
    -- LOCAL.overlapFn = ensure overlapping(x.shape, y.shape)
    -- LOCAL.labelFn1  = ensure outsideOf(y.text, x.shape)
    -- LOCAL.labelFn2  = ensure outsideOf(x.text, y.shape)
}

Point p {
      p.offset = 10.0
      p.shape = Circle {
      	      strokeWidth = 0
	      color = rgba(0.0, 0.0, 0.0, 1.0)
	      r = 3.0
      }

      p.text = Text {
	string = p.label
	x = p.shape.x + p.offset
	y = p.shape.y + p.offset
      }
}
